package com.ocr;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.imageio.ImageIO;

import com.google.gson.Gson;


public class J {
	
	/**
	 * ��ȡrbg��ɫ
	 * @param img
	 * @param x
	 * @param y
	 * @return
	 */
	private Map<String, Integer> GetPixel(BufferedImage img,int x, int y) {
		Map<String, Integer> rgbMap = new TreeMap<String, Integer>();
		rgbMap.put("R", (img.getRGB(x, y) & 0xff0000 ) >> 16); 
		rgbMap.put("G",(img.getRGB(x, y) & 0xff00 ) >> 8); 
		rgbMap.put("B",(img.getRGB(x, y) & 0xff)); 
        return rgbMap;
	}
	
	/**
	 * �������ؽ���OCR�ԱȽ���
	 * @return
	 */
	private int fixOCRRBG(Map<String, Integer> color) {
		return ((((color.get("R") * 0x4c8b) + (color.get("G") * 0x9645)) + (color.get("B") * 0x1d30)) >> 0x10);
	}
	
	public BufferedImage getBufferedImage(String filePath) throws IOException {
		File file  = new File(filePath);
		 int[][] result = null;
         if (!file.exists()) {
              return null;
         }
         BufferedImage bufImg = ImageIO.read(file);
         return bufImg;
	}
	
	/**
	 * ����ͼƬ
	 * @param img
	 * @return
	 */
	public  int[][] fixImg(BufferedImage img) {

		int nImageDate[][] = new int[img.getHeight()][img.getWidth()];
		for (int i = 0; i < img.getHeight(); i++) {
			for (int j = 0; j < img.getWidth(); j++) {
				if (170 < fixOCRRBG(GetPixel(img, j, i))) {
					nImageDate[i][j] = 0;
				} else {
					nImageDate[i][j] = 1;
				}
			}
		}
		return nImageDate;
	}
	
	
	 public String a(List<F> A_0)
	    {
	        StringBuilder builder = new StringBuilder();
	        Collections.sort(A_0);
	        Map list = new TreeMap();
	        for (int i = 0; i < 4; i++)
	        {
	            if (A_0.size() < 4)
	            {
	                return "";
	            }
	            list.put(A_0.get(i).d(), A_0.get(i));
	            for (int j = i + 1; j < A_0.size(); j++)
	            {
	                if (Math.abs((int) (A_0.get(i).d() - A_0.get(j).d())) < 3)
	                {
	                    if (((F) list.get(A_0.get(i).d())).a() < A_0.get(j).a())
	                    {
	                        list.put(A_0.get(i).d(),A_0.get(j));
	                    }
	                    A_0.remove(j);
	                    j--;
	                }
	            }
	        }
	        
	        for (Object o : list.keySet()) {
	        	Object o1 = list.get(o);
				 builder.append(((F)list.get(o)).b());
			}
	        return builder.toString();
	    }
	
	 private static int a(int A_0)
	    {
	        int num = 0;
	        while (num < A_0)
	        {
	            num++;
	            A_0 &= A_0 - 1;
	        }
	        return num;
	    }
	 
	public List<F> a(B A_0, Map A_1) {
		 List<F> list = new ArrayList<F>();
		 for (Object o : A_1.keySet()) {
			for (int j = 0; j < A_0.count()-1; j++) {
				int num3 = A_0.count() - ((((B)A_1.get(o)).count()/2)+j);
				for (int k = 0; k <= A_0.d(); k++) {
					int num5 = k - (((B)A_1.get(o)).d() / 2);
					if(num5 < 0) {
						num5 = 0;
					}
					int num6 = ((((B)A_1.get(o)).d() + 1) / 2) + k;
					if (num6 > A_0.d()) {
						num6 = A_0.d();
					}
                    int num8 = 0;
                    int num9 = 0;
                    int num7 = num5;
                    while (num7 < num6) {
                    	int num10;
                    	int num11 = (((((B)A_1.get(o)).d() / 2) - k) > 0) ? ((((B)A_1.get(o)).d() / 2) - k) : 0;
                    	 if (num3 > 0)
	                        {
	                            num10 = ((B)A_1.get(o)).a().get((num11 + num7) - num5) << (num3 & 0x1f);
	                        }
	                        else
	                        {
	                            num10 = ((B)A_1.get(o)).a().get((num11 + num7) - num5) >> ((num3 * -1) & 0x1f);
	                        }
	                        num10 &= ((int) Math.pow(2.0, (double) A_0.count())) - 1;
	                        num8 += a(num10);
	                        if (num8 == 0)
	                        {
	                            num9++;
	                        }
	                        if (((num10 & A_0.a().get(num7)) ^ num10) != 0)
	                        {
	                            break;
	                        }
	                        num7++;
                    }
                    if ((num7 == num6) && (num8 != 0))
                    {
                        if (num3 > 0)
                        {
                            if ((((B)A_1.get(o)).count() + num3) < A_0.count())
                            {
                                ((B)A_1.get(o)).count();
                            }
                            else
                            {
                                A_0.count();
                            }
                        }
                        else
                        {
                        	((B)A_1.get(o)).count();
                        }
                        F item = new F(((B)A_1.get(o)).b_char(), num5 + num9, ((float) num8) / ((float) ((B)A_1.get(o)).g()), ((B)A_1.get(o)).g());
                        list.add(item);
                    }
				}
			}
		}
	        return list;
	}
	
	
	
	public String fixCode(BufferedImage img) {
		B b = new B(this.fixImg(img));
		Map bArray = K.key();
		String code = a(a(b, bArray));
//		code = code.substring(2,3)+code.substring(1,2)+code.substring(0,1)+code.substring(3);
		return code;
	}
	
	public static void main(String[] args) {
		J j = new J();
		try {
			BufferedImage img = j.getBufferedImage("C:\\Users\\joinchen\\Desktop\\passCodeAction");
			String code = j.fixCode(img);
			
			System.out.println(code);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
